import Foundation
import Testing
@testable import MgAuthInterceptor


@Test func example() async throws {
    // Write your test here and use APIs like `#expect(...)` to check expected conditions.

}


/**
老actor中的方法，这里写法，看着比较新颖，留着以后参考
 if isRefreshing {
	 
	 return try await withCheckedThrowingContinuation { continuation in
		 refreshContinuations.append(continuation)
	 }
 }
/// 加了 actor ，会自动保证该对象访问在多线程中是安全的，不会出现数据竞争
/// 使用的时候，在外部创建一个单利使用
public Actor TokenManager {

	private let provider: TokenProvider
	private var isRefreshing: Bool = false
	private var refreshContinuations: [CheckedContinuation<Void, Error>] = []
	
	
	
	public init(provider: TokenProvider) {
		self.provider = provider
		
	}
	
	
	
	/// 校验请求所需的 Token 是否有效
	///
	/// - 如果 `provider.requiresValidToken` 返回 true，表示该请求需要验证 Token。
	/// - 接着通过 `provider.isTokenValid` 判断当前 Token 是否仍然有效。
	/// - 若 Token 已失效，则通过 `provider.refreshToken` 获取新的有效 Token。
	///
	/// - Parameter request: 待校验的请求
	public func validToken(for request: URLRequest) async throws {
		
		guard await provider.requiresValidToken(request) else { return }
		
		guard await !provider.isTokenValid() else { return }
		
		if isRefreshing {
			
			return try await withCheckedThrowingContinuation { continuation in
				refreshContinuations.append(continuation)
			}
		}
		
		isRefreshing = true
		
		var currentRetry = 0
		let maxRefreshRetryCount = provider.maxRefreshRetryCount
		let refreshRetryDelayNanoseconds = provider.refreshRetryDelayNanoseconds
		
		
			
		defer {
			
			isRefreshing = false
			
			refreshContinuations.forEach { $0.resume() }
			refreshContinuations.removeAll()
		}
		
		while true {
			
			do {
				try await provider.refreshToken()
				break // 刷新成功，跳出循环
			}catch {
				currentRetry += 1
				if currentRetry >= maxRefreshRetryCount {
					throw error
				}
				
				try await Task.sleep(nanoseconds: refreshRetryDelayNanoseconds)
			}
		}
	
	}
	
	/// 构造已授权的请求（如有必要自动刷新 Token）
	///
	/// 此方法将自动校验请求是否需要 Token，如果需要：
	/// - 若当前 Token 有效，直接将其注入请求头中；
	/// - 若当前 Token 已过期，则自动刷新 Token 后再注入；
	///
	/// 如果该请求不需要验证 Token，则会原样返回请求。
	///
	/// - Parameter request: 原始 `URLRequest` 请求
	/// - Returns: 注入了有效 Token 的请求
	/// - Throws: 如果 Token 刷新失败，抛出对应错误
	public func authorizedRequest(for request: URLRequest) async throws -> URLRequest {
		try await validToken(for: request)
		return try await provider.authorized(request)
	}
	
	/// 发起带 token 的请求，如遇 401 自动刷新并重试一次
	public func performAuthorizedRequest(
		_ request: URLRequest,
		maxRetryCount: Int = 1,
		retryDelayNanoseconds: UInt64 = 500_000_000,
		using session: URLSession =  .shared
	) async throws  -> (Data, URLResponse) {
		
		var currentRetryCount = 0
		
		while true {
			do {
				
				let authorizedRequest = try await authorizedRequest(for: request)
				let (data, response) = try await session.data(for: authorizedRequest)

				if await provider.shouldRefreshToken(request: request, response: response, data: data) {
					try await validToken(for: request)
					continue
				}
	

				// 请求成功且无需刷新 token，直接返回
				return (data, response)

			} catch {
				
				currentRetryCount += 1
				if currentRetryCount >= maxRetryCount {
					throw error
				}
				try? await Task.sleep(nanoseconds: retryDelayNanoseconds)
			}
		}
	}
}
 */
